package com.demo.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.alibaba.fastjson.JSONObject;

@Component
@WebFilter(filterName = "ThreadContextFilter", urlPatterns = "/")
public class ShortUrlMappingFilter implements Filter{

	private Log log = LogFactory.getLog(this.getClass()) ;
	
	private final int SHORTKEY_LENGTH = 6 ;
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		this.log.info("url mapping start ... ");
		
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		
		String uri = httpRequest.getRequestURI() ; // 域名后面所有内容
		String shortKey = uri.substring(1); // 去除第一个斜杠，得到6位短链接Key
		
		// 根据位数，判断是否是短链接请求 【Server可能接收到非短链接请求】
		if(this.SHORTKEY_LENGTH == shortKey.trim().length()) {
			// 1. 根据短链Key，获取原URL
			
			BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(httpRequest.getServletContext()) ;
			RestTemplate restTemplate = (RestTemplate) factory.getBean("restTemplate") ;
			
			// 准备请求参数
			JSONObject jsonParam = new JSONObject();
			jsonParam.put("shortKey", shortKey) ;
			// 设置请求类型
			HttpHeaders httpHeaders = new HttpHeaders();
	        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
	        // 封装参数和头信息
	        HttpEntity<JSONObject> httpEntity = new HttpEntity<JSONObject>(jsonParam,httpHeaders);
	        String url = "http://localhost:8080/short/query" ; 
	        String longUrlStr = null ;
			try {
				longUrlStr = restTemplate.postForObject(url, httpEntity, String.class) ;
			}catch(RestClientException e) {
				this.log.error("rest error! "+e.getMessage());
			}
			
			if(StringUtils.isEmpty(longUrlStr)) {
			// 2. 若获取原URL失败，则抛错
				this.log.error("longUrl is null !!") ;
				throw new ServletException();
			}else {
			// 3. 获取原URL成功，进行302重定向
				this.log.info("redirecting to longUrl: " + longUrlStr) ;
				httpResponse.setStatus(302);
				httpResponse.setHeader("Location", longUrlStr);
//				httpResponse.sendRedirect(longUrlStr);  //该方法跟上面两句方法的效果相同
			}
			
		}else {
			this.log.info("非短链请求，执行后续逻辑") ; 
			//根据需要，可以报错拦截，也可以请求到后续Filter以及Controller
//			chain.doFilter(httpRequest, httpResponse);
		}
		
	}

}
